<template>
  <div
    class="art-table"
    :class="{ 'header-background': showHeaderBackground }"
    :style="{
      marginTop: marginTop + 'px',
      height: total ? 'calc(100% - 90px)' : 'calc(100% - 55px)'
    }"
  >
    <div class="table-container">
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="tableData"
        :row-key="rowKey"
        :height="height"
        :max-height="maxHeight"
        :show-header="showHeader"
        :highlight-current-row="highlightCurrentRow"
        :size="tableSizeComputed"
        :stripe="stripeComputed"
        :border="borderComputed"
        :header-cell-style="{
          backgroundColor: showHeaderBackground ? 'var(--el-fill-color-lighter)' : '',
          fontWeight: '500'
        }"
        @row-click="handleRowClick"
        @selection-change="handleSelectionChange"
      >
	  
	  <el-table-column
	    v-if="index && tableData.length > 0"
	    type="index"
	    width="60"
	    label="序号"
	    align="center"
	    fixed="left"
	  />
	  
	  
		<slot v-if="tableData.length"></slot>

        <!-- 动态列（根据列配置生成） -->
        <template v-for="col in columns " :key="col.name">
          <el-table-column
			:label="col.label"
			:prop="col.prop"
			:fixed="col.fixed"
			:align="col.align"
			:sortable="col.sortable"
			:width="col.width"
			:sort-orders="['ascending', 'descending']"
          >
          </el-table-column>
        </template> 
		
<!-- 		<template v-for="col in columns " :key="col.name">
		  <el-table-column
		    v-if="col.isVisible=='0'"
		    v-bind="col" 
			:width="col.width==0 ? 'auto':  col.width "
		    :min-width="col.minWidth"
		    :align="col.align || 'left'"
		    :fixed="col.fixed"
		    :sortable="col.sortable=='0'"
		    :sort-orders="['ascending', 'descending']"
			:formatter="getFormatter(col)"
		  >
		  </el-table-column>
		</template> -->


        <!-- 空数据 -->
        <template #empty>
          <el-empty :description="emptyText" v-show="!loading" />
        </template>
      </el-table>
    </div>

    <!-- 分页  v-if="isPagination"-->
    <div
      class="table-pagination "
      :class="paginationAlign "
    >
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="pageSizes"
        :pager-count="isMobile ? 5 : 7"
        :total="total"
        :background="true"
        :size="paginationSize"
        :layout="paginationLayoutComputed"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    
	<!-- :hide-on-single-page="hideOnSinglePage" -->
	
    <!-- 加载状态指示器 -->
    <div v-if="loading" class="loading-overlay">
      <div class="loading-spinner">
        <el-icon class="is-loading" :size="32">
          <Loading />
        </el-icon>
        <div class="loading-text">加载中...</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, shallowRef, onMounted } from 'vue';
import { useWindowSize } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useTableStore } from '@/store/modules/table';
import { useDictStore } from '@/store/modules/dict';
import dayjs from 'dayjs';
import { RuleService } from '@/api/data-rule/ruleApi';
import { Loading } from '@element-plus/icons-vue';
import { number } from 'echarts';
import { useCheckedColumns } from '@/composables/useCheckedColumns'
const { width } = useWindowSize();
const isMobile = computed(() => width.value < 768);
const dictStore = useDictStore();

interface TableProps {
  data?: any[];
  columns?: any[];
  loading?: boolean;
  rowKey?: string;
  border?: boolean | null;
  stripe?: boolean | null;
  index?: boolean;
  indexFixed?: boolean | 'left' | 'right';
  height?: string | number;
  maxHeight?: string | number;
  showHeader?: boolean;
  highlightCurrentRow?: boolean;
  emptyText?: string;
  pagination?: boolean;
  currentPage?: number;
  pageSize?: number;
  pageSizes?: number[];
  hideOnSinglePage?: boolean;
  paginationAlign?: 'left' | 'center' | 'right';
  paginationSize?: 'small' | 'default' | 'large';
  paginationLayout?: string;
  showHeaderBackground?: boolean | null;
  marginTop?: number;
  size?: 'small' | 'default' | 'large';
  showSelection?: boolean;
  showExpand?: boolean;
  showActions?: boolean;
  actionColumnLabel?: string;
  actionColumnWidth?: string | number;
  actionColumnFixed?: boolean | 'left' | 'right';
  remoteSort?: boolean;
  rule?:string;
  fetchData?: (params?: any) => Promise<any>
  autoLoad?: boolean
  customFormatters?: Record<string, (value: any, row: any) => any>
}

const props = withDefaults(defineProps<TableProps>(), {
  data: () => [],
  columns: () => [],
  loading: false,
  rowKey: 'id',
  border: null,
  stripe: null,
  index: false,
  indexFixed: false,
  height: '100%',
  showHeader: true,
  highlightCurrentRow: false,
  emptyText: '暂无数据',
  pagination: true,
  currentPage: 1,
  pageSize: 20,
  hideOnSinglePage: true,
  pageSizes: () => [10, 20, 30, 50],
  paginationAlign: 'center',
  paginationSize: 'default',
  paginationLayout: '',
  showHeaderBackground: null,
  marginTop: 20,
  size: 'default',
  showSelection: false,
  showExpand: false,
  showActions: false,
  actionColumnLabel: '操作',
  actionColumnWidth: '150',
  actionColumnFixed: 'right',
  remoteSort: false,
  rule: '',
  fetchData: () => Promise.resolve({}),
  autoLoad: true,
  customFormatters: () => ({})
});

const DEFAULT_PLACEHOLDER = '-';

// 计算分页布局
const paginationLayoutComputed = computed(() => {
  return props.paginationLayout || (
    isMobile.value 
      ? 'prev, pager, next, jumper, sizes, total' 
      : 'total, sizes, prev, pager, next, jumper'
  );
});

const emit = defineEmits([
  'update:currentPage',
  'update:pageSize',
  'update:total',
  'row-click',
  'size-change',
  'current-change',
  'selection-change',
  'sort-change',
  'reload',
  'loading',
  'update:data',
  'columns',
]);

const tableStore = useTableStore();
const { tableSize } = storeToRefs(tableStore);

// 表格实例（使用 shallowRef 优化性能）
const tableRef = shallowRef();
const loading = ref(props.loading);

// 当前页
const currentPage = computed({
  get: () => props.currentPage,
  set: (val) => emit('update:currentPage', val)
});

// 每页条数
const pageSize = computed({
  get: () => props.pageSize,
  set: (val) => emit('update:pageSize', val)
});

// 计算属性（缓存结果提升性能）
const tableSizeComputed = computed(() => props.size || tableSize.value);
const stripeComputed = computed(() => props.stripe ?? tableStore.isZebra);
const borderComputed = computed(() => props.border ?? tableStore.isBorder);
const showHeaderBackground = computed(() => 
  props.showHeaderBackground ?? tableStore.isHeaderBackground
);

const total = ref<number>(0);
const tableData=ref<any[]>([]);

// 是否显示分页
const showPagination = computed(() => {
  return props.pagination && total.value > 0 && 
    !(props.hideOnSinglePage && total.value <= props.pageSize);
});

// 统一格式化函数
const getFormatter = (col: any) => {
	
  // 优先使用自定义格式化函数
  if (props.customFormatters[col.name!]) {
	return (row: any) => props.customFormatters[col.name!](row[col.name!], row)
  }
  
  // 日期格式化
  if (col.dataType === 'Date' && col.displayFormat) {
	return (row: any) => 
	  row[col.name!] ? dayjs(row[col.name!]).format(col.displayFormat) : DEFAULT_PLACEHOLDER
  }
  
  // 常量映射
  if (col.mapping === 'const' && col.mappingInfo) {
	try {
	  const mapping = JSON.parse(col.mappingInfo)
	  return (row: any) => {
		const value = row[col.name!] ?? ''
		return mapping[String(value)] || DEFAULT_PLACEHOLDER
	  }
	} catch (e) {
	  console.error('常量映射解析错误:', e)
	  return () => DEFAULT_PLACEHOLDER
	}
  }
  
  // 字典映射
  if (col.mapping === 'dict' && col.mappingKey) {
	return (row: any) => {
	  const value = row[col.name!] ?? ''
	  return dictStore.getDictMappingValue(col.mappingKey!, String(value)) || DEFAULT_PLACEHOLDER
	}
  }
  
  return (row: any) => {
	  return col.name.split('.').reduce((acc: { [x: string]: any; } | null | undefined, part: string | number) => {
	    if (acc === null || acc === undefined) return undefined;
	    return acc[part];
	  }, row);
  }
}

// 事件处理函数
const handleRowClick = (row: any, column: any, event: any) => {
  emit('row-click', row, column, event);
};

const handleSelectionChange = (selection: any) => {
  emit('selection-change', selection);
};

const handleSortChange = ({ prop, order }: any) => {
  if (props.remoteSort) {
    emit('sort-change', { prop, order });
  }
};

const handleSizeChange = (val: number) => {
  emit('size-change', val);
  scrollToTop();
};

const handleCurrentChange = (val: number) => {
  emit('current-change', val);
  scrollToTop();
};

// 表格滚动到顶部（使用 requestAnimationFrame 优化）
const scrollToTop = () => {
  requestAnimationFrame(() => {
    if (tableRef.value) {
      tableRef.value.setScrollTop(0);
    }
  });
};

// 重新加载数据
const reload = (params?: any) => {
  loadData(params);
  emit('reload', params);
};

// 清空选择
const clearSelection = () => {
  tableRef.value?.clearSelection();
};

// 切换行选择状态
const toggleRowSelection = (row: any, selected: boolean) => {
  tableRef.value?.toggleRowSelection(row, selected);
};

// 切换行展开状态
const toggleRowExpansion = (row: any, expanded: boolean) => {
  tableRef.value?.toggleRowExpansion(row, expanded);
};

// 设置当前行
const setCurrentRow = (row: any) => {
  tableRef.value?.setCurrentRow(row);
};

// 暴露方法给父组件
defineExpose({
  reload,
  clearSelection,
  toggleRowSelection,
  toggleRowExpansion,
  setCurrentRow,
  getTableRef: () => tableRef.value,
  getColumns: () => columns.value,
  columnChecks:()=>columnChecks.value
});


const isPagination=ref<boolean>();

const {allColumns, columnChecks, columns} = useCheckedColumns(() => []);
// 加载列配置
const fetchColumns = async () => {
  // 验证规则是否存在
  if (!props.rule) {
    console.warn('未提供规则名称，无法加载列配置');
    return;
  }
  try {
    const { rule,fields } = await RuleService.getColumns(props.rule);
	// 验证响应数据
	if (!Array.isArray(fields)) {
	  throw new Error('返回的字段配置不是数组格式');
	}
	for(var col of fields){
		allColumns.push({
			prop: col.name,
			label: col.label,
			checked: col.isVisible=='0'
		})
		columnChecks.value.push(
			{
				prop: col.name,
				label: col.label,
				checked: col.isVisible=='0'
			}
		)
		columns.value.push({
			prop: col.name,
			align:col.align,
			label: col.label,
			width: col.width==0 ? 'auto':  col.width,
			fixed: col.fixed,
			sortable: col.sortable=='0',
		});
	}
	isPagination.value = rule.pagination === '0';
	emit('columns', columnChecks.value);
  } catch (error) {
    console.error('列配置加载失败', error);
  }
};

// 加载表格数据
const loadData = async (params?: any) => {
	loading.value = true;
	emit('loading', true);
	try {
		if(isPagination.value==true){
			const { list, totalRow } = await props.fetchData({});
			emit('update:data', list);
			tableData.value=list;
			total.value=totalRow
		}
		else{
			const data = await props.fetchData(params);
			tableData.value=data;
			emit('update:data', data);
		}
	} catch (error) {
		console.error('数据加载失败', error);
		tableData.value=[];
		emit('update:data', []);
	} finally {
		loading.value = false;
		emit('loading', false);
	}
};

// 监听loading状态变化
watch(() => props.loading, (val) => {
  loading.value = val;
});

// 监听rule变化
watch(() => props.rule, async (newVal) => {
  if (newVal) {
    await fetchColumns();
    if (props.autoLoad) loadData();
  }
});

onMounted(async () => {
  await fetchColumns();
  if (props.autoLoad) {
    loadData();
  }
});
</script>

// .art-table {
//   --table-header-bg: var(--el-fill-color-lighter);
//   
//   --pagination-margin: 0px;
//   --pagination-padding: 10px 0;
  
//   position: relative;
//   display: flex;
//   flex-direction: column;
//   height: 100%;
//   background-color: #fff;
//   border-radius: 0px;
//   overflow: hidden;
//   //box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
//   .table-container {
//     flex: 1;
//     overflow: hidden;
//   }

//   .table-pagination {
//     display: flex;
//     margin-top: var(--pagination-margin);
//     padding: var(--pagination-padding);
//     background-color: #fff;
//     border: 1px solid var(--el-table-border-color);
//     &.left { justify-content: flex-start; }
//     &.center { justify-content: center; }
//     &.right { justify-content: flex-end; }
//   }
  
//   .loading-overlay {
//     position: absolute;
//     top: 0;
//     left: 0;
//     right: 0;
//     bottom: 0;
//     background-color: rgba(255, 255, 255, 0.7);
//     display: flex;
//     align-items: center;
//     justify-content: center;
//     z-index: 10;
    
//     .loading-spinner {
//       display: flex;
//       flex-direction: column;
//       align-items: center;
      
//       .loading-text {
//         margin-top: 12px;
//         color: var(--el-color-primary);
//         font-weight: 500;
//       }
//     }
//   }

//   // 表头样式
//   &.header-background {
//     :deep(.el-table) {
//       th.el-table__cell {
//         background-color: var(--table-header-bg);
//       }
//     }
//   }
// }

// // 表格样式优化
// :deep(.el-table) {
//   th.el-table__cell {
//     font-weight: 600;
//     color: #333;
//   }
  
//   .el-table__empty-block {
//     display: flex;
//     justify-content: center;
//     align-items: center;
//     height: 100%;
//     min-height: 300px;
//   }
  
//   .el-table__body {
//     tr:hover > td {
//       background-color: #f5f7fa;
//     }
//   }
//   .el-table__inner-wrapper:before{
// 	  border: none !important;
// 	  background: none !important;
//   }
// }

// // 移动端适配
// @media (max-width: 768px) {
//   .art-table {
//     border-radius: 0;
//     box-shadow: none;
//     margin-top: 0;
    
//     .table-container {
//       padding: 0;
//     }
    
//     :deep(.el-table) {
//       font-size: 13px;
      
//       .el-table__cell {
//         padding: 8px 0;
//       }
//     }
//   }
  
//   :deep(.el-pagination) {
//     flex-wrap: wrap;
//     justify-content: center;
    
//     .el-pagination__sizes,
//     .el-pagination__jump {
//       margin-top: 10px;
//       width: 100%;
//       justify-content: center;
//     }
//   }
// }


<style lang="scss" scoped>
	
  .art-table {
	  
	 --table-border-color: var(--el-table-border-color);
	 
    .table-container {
      height: 100%;
    }
	
    .table-pagination {
      display: flex;
      margin-top: 8px;

      // 分页对齐方式
      &.left {
        justify-content: flex-start;
      }

      &.center {
        justify-content: center;
      }

      &.right {
        justify-content: flex-end;
      }
    }

    :deep(.el-table) {
      th.el-table__cell {
        font-weight: 600;
      }
    }

    &.header-background {
      :deep(.el-table) {
        th.el-table__cell {
          background-color: var(--el-fill-color-light);
        }
      }
    }
  }

  // 移动端分页
  @media (max-width: $device-phone) {
    :deep(.el-pagination) {
      display: flex;
      flex-wrap: wrap;
      gap: 15px 0;
      align-items: center;
      justify-content: center;

      .el-pagination__sizes {
        .el-select {
          width: 100px !important;

          .el-select__wrapper {
            height: 30px !important;
          }
        }
      }

      .el-pager {
        li {
          margin-right: 2px;
        }
      }

      .el-pagination__jump {
        margin-left: 5px;

        .el-input {
          height: 32px !important;
        }
      }
    }
  }
</style>